// StpLibrary - by Steve T. Pham
// http://www.geocities.com/stevetpham

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
//using StpLibrary.Utilities;
using SteveTPham.QueryAnything.DataAccess;
using SteveTPham.QueryAnything.Utilities;

namespace SteveTPham.QueryAnything.Controls
{
	public partial class SimpleDataSetViewer : UserControl
	{
		public event CellChangedEventHandler CellChanged = null;
		private DataSet ds = null;
		private int currentRow = -1;
		private int currentColumn = -1;
		private DataGridViewSelectionMode selectedMode = DataGridViewSelectionMode.RowHeaderSelect;

		public SimpleDataSetViewer()
		{
			InitializeComponent();
		}

		#region Events
		private void SimpleDataSetViewer_Load(object sender, EventArgs e)
		{
			lblStatus.Text = "";
		}


		private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
		{
			TableName = comboBox1.SelectedItem.ToString();
		}

		private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
		{
			TableName = listBox1.SelectedItem.ToString();
		}

		private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
		{
			showTableListToolStripMenuItem.Checked = !splitContainer1.Panel1Collapsed;
		}

		private void showTableListToolStripMenuItem_Click(object sender, EventArgs e)
		{
			HideTablePanel = !HideTablePanel;
		}

		private void lblTable_Click(object sender, EventArgs e)
		{
			HideTablePanel = !HideTablePanel;
		}

		private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
		{
			try
			{
				currentRow = e.RowIndex;
				currentColumn = e.ColumnIndex;

				lblStatus.Text = string.Format("Row: {0} of {1} Col: {2} of {3}",
					1 + e.RowIndex, dataGridView1.Rows.Count,
					1 + e.ColumnIndex, dataGridView1.Columns.Count
					);

				if (CellChanged != null)
				{
					CellChangedEventArgs e2 = new CellChangedEventArgs(
						TableName, ColumnName, this.SelectedTableIndex,
						this.SelectedRowIndex, this.SelectedColumnIndex);
					CellChanged(sender, e2);
				}
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e)
		{
		}
		#endregion

		#region Private methods
		private void PopulateTables()
		{
			if (ds == null)
				return;

			comboBox1.Items.Clear();
			listBox1.Items.Clear();

			for (int i = 0; i < ds.Tables.Count; i++)
			{
				comboBox1.Items.Add(ds.Tables[i].TableName);
				listBox1.Items.Add(ds.Tables[i].TableName);
			}

			comboBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;
			listBox1.SelectedIndex = comboBox1.Items.Count > 0 ? 0 : -1;
		}
		#endregion

		#region Public methods
		public void Initialize()
		{
			if (ds == null || ds.Tables.Count == 0 || !string.IsNullOrEmpty(TableName))
				return;

			TableName = ds.Tables[0].TableName;
		}

		public void SetBackColorByColumns(Color backColor, Color selectionBackColor, params TableColumn[] tcList)
		{
			// get only the columns for processing
			//string[] columns = new string[tcList.Length];
			List<string> columns = new List<string>();

			for (int i = 0; i < tcList.Length; i++)
			{
				TableColumn tc = tcList[i];

				if (tc.TableName.ToUpper() != TableName.ToUpper())
					continue;

				columns.Add(tcList[i].ColumnName.ToUpper());
			}

			columns.Sort();
			string[] colArray = columns.ToArray();
			//Array.Sort(columns);

			foreach (DataGridViewColumn col in dataGridView1.Columns)
			{
				string headerText = col.HeaderText.ToUpper();
				bool found = Array.BinarySearch(colArray, headerText) >= 0;
				col.DefaultCellStyle.BackColor = (found) ? backColor : Color.White;
				col.DefaultCellStyle.SelectionBackColor = (found) ? selectionBackColor : Color.Black;
				col.Tag = found;
			}
		}
		#endregion

		#region Public events
		public event EventHandler DataMemberChanged
		{
			add
			{
				dataGridView1.DataMemberChanged += value;
			}
			remove
			{
				dataGridView1.DataMemberChanged -= value;
			}
		}

		public event EventHandler CellDoubleClick
		{
			add
			{
				dataGridView1.DoubleClick += value;
			}
			remove
			{
				dataGridView1.DoubleClick -= value;
			}
		}
		#endregion

		#region Public properties
		public DataSet DataSource
		{
			get
			{
				return ds;
			}
			set
			{
				ds = value;
				dataGridView1.DataSource = ds;
				PopulateTables();
				Initialize();
			}
		}

		public string TableName
		{
			get
			{
				return dataGridView1.DataMember;
			}
			set
			{
				#region Change DataMember (with support for SelectionMode)
				{
					#region Change DataMember with rollback
					string previousMember = dataGridView1.DataMember;
					DataGridViewSelectionMode previousMode = dataGridView1.SelectionMode;

					try
					{
						dataGridView1.DataMember = value;
					}
					catch (Exception ex)
					{
						// BUGGY: DataMember does not restore previous value of DataMember...  we must do it here.
						try
						{
							dataGridView1.DataMember = previousMember;
						}
						catch //(Exception ex2)
						{
							// ignore exception.
						}

						if (ex.Message != @"Column's SortMode cannot be set to Automatic while the DataGridView control's SelectionMode is set to FullColumnSelect.")
							throw;

						try
						{
							// try changing the SelectionMode to default, first
							dataGridView1.SelectionMode = DataGridViewSelectionMode.RowHeaderSelect;
							dataGridView1.DataMember = value;
						}
						catch (Exception ex2)
						{
							try
							{
								// restore previous value of SelectionMode.
								dataGridView1.SelectionMode = previousMode;
							}
							catch
							{
								// ignore exception.
							}
							throw ex2;
						}
					}
					#endregion

					if (SelectionMode != DataGridViewSelectionMode.RowHeaderSelect)
					{
						for (int i = 0; i < dataGridView1.Columns.Count; i++)
						{
							DataGridViewColumn c = dataGridView1.Columns[i];
							c.SortMode = DataGridViewColumnSortMode.NotSortable;
						};
					}
					dataGridView1.SelectionMode = SelectionMode;
				}
				#endregion

				#region Change ComboBox
				if (!string.IsNullOrEmpty(value) && comboBox1.SelectedItem != null && value.ToUpper() != comboBox1.SelectedItem.ToString().ToUpper())
				{
					string v2 = value.ToUpper();
					for (int i = 0; i < comboBox1.Items.Count; i++)
					{
						string v = comboBox1.Items[i].ToString().ToUpper();

						if (v == v2)
						{
							comboBox1.SelectedIndex = i;
							break;
						}
					}
				}
				#endregion

				#region Change ListBox
				if (!string.IsNullOrEmpty(value) && listBox1.SelectedItem != null && value.ToUpper() != listBox1.SelectedItem.ToString().ToUpper())
				{
					string v2 = value.ToUpper();
					for (int i = 0; i < listBox1.Items.Count; i++)
					{
						string v = listBox1.Items[i].ToString().ToUpper();

						if (v == v2)
						{
							listBox1.SelectedIndex = i;
							break;
						}
					}
				}
				#endregion

				dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
			}
		}

		public void AutoResizeColumns(DataGridViewAutoSizeColumnsMode mode)
		{
			dataGridView1.AutoResizeColumns(mode);
		}

		public string ColumnName
		{
			get
			{
				#region Sanity Checks
				if (dataGridView1 == null)
					return string.Empty;
				#endregion

				//string s = dataGridView1.Columns[currentColumn].HeaderText;

				for (int i = 0; i < dataGridView1.Columns.Count; i++)
				{
					DataGridViewColumn c = dataGridView1.Columns[i];
					if (c.Selected)
						return c.HeaderText;
				}

				if (currentColumn == -1)
					return string.Empty;
				else
					return dataGridView1.Columns[currentColumn].HeaderText;
			}
			set
			{
				for (int i = 0; i < dataGridView1.Columns.Count; i++)
				{
					DataGridViewColumn c = dataGridView1.Columns[i];
					c.Selected = false;
				}

				for (int i = 0; i < dataGridView1.Columns.Count; i++)
				{
					DataGridViewColumn c = dataGridView1.Columns[i];
					c.Selected = c.HeaderText.ToUpper() == value.ToUpper();
					if (c.Selected)
						currentColumn = i;
				}
			}
		}

		public int Count
		{
			get
			{
				if (ds == null)
					return -1;
				else
					return ds.Tables.Count;
			}
		}

		public int SelectedTableIndex
		{
			get
			{
				return comboBox1.SelectedIndex;
			}
		}

		public int SelectedRowIndex
		{
			get
			{
				return currentRow;
			}
		}

		public int SelectedColumnIndex
		{
			get
			{
				return currentColumn;
			}
		}

		public DataGridView DataGridView
		{
			get
			{
				return dataGridView1;
			}
		}

		public DataGridViewSelectionMode SelectionMode
		{
			get
			{
				return selectedMode;
			}
			set
			{
				selectedMode = value;
			}
		}

		public bool HideTablePanel
		{
			get
			{
				return splitContainer1.Panel1Collapsed;
			}
			set
			{
				splitContainer1.Panel1Collapsed = value;
			}
		}

		public DataGridViewCell SelectedCell
		{
			get
			{
				return dataGridView1.Rows[SelectedRowIndex].Cells[SelectedColumnIndex];
			}
			//set
			//{
			//}
		}
		#endregion

		private void analyzeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			try
			{
				//using (DataTableAnalysisTool f = new DataTableAnalysisTool())
				//{
				//    f.DataSource = ds.Tables[TableName];
				//    f.ShowDialog();
				//}
			}
			catch (Exception ex)
			{
				FormUtil.WinException(ex);
			}
		}

		private void viewTextToolStripMenuItem_Click(object sender, EventArgs e)
		{
			try
			{
				//Common.ShowTextDialog(SelectedCell.Value.ToString(), "View Text");
			}
			catch (Exception ex)
			{
				FormUtil.WinException(ex);
			}
		}
	}

	#region Delegate
	public delegate void CellChangedEventHandler(object sender, CellChangedEventArgs e);

	public class CellChangedEventArgs : EventArgs
	{
		public readonly string TableName;
		public readonly string ColumnName;
		public readonly int TableIndex;
		public readonly int RowIndex;
		public readonly int ColumnIndex;
		//public readonly string DataType;
		//public readonly bool IsNullable;

		public CellChangedEventArgs()
		{
		}

		public CellChangedEventArgs(string tableName, string columnName,
			int tableIndex, int rowIndex, int columnIndex)
		{
			this.TableName = tableName;
			this.ColumnName = columnName;
			this.TableIndex = tableIndex;
			this.RowIndex = rowIndex;
			this.ColumnIndex = columnIndex;
		}
	}
	#endregion

}
